package org.javahispano.javacup.tacticas_aceptadas.jmperez;

import java.awt.Color;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import org.javahispano.javacup.modelo.*;

public class CeutaCupWarriors implements Tactica {

	private static int INDICE_PORTERO = 0;
	private static double RADIO_SEGURIDAD_PASE = 8;
	private static double MAXIMA_DISTANCIA_PASE = 40;
	
	//GANANDO A
    Posicion alineacion1[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(7.37062937062937,-35.8710407239819),
            new Posicion(-8.083916083916083,-35.63348416289593),
            new Posicion(-10.937062937062937,-8.789592760180994),
            new Posicion(-0.951048951048951,-30.88235294117647),
            new Posicion(9.748251748251748,-8.789592760180994),
            new Posicion(-16.88111888111888,14.728506787330318),
            new Posicion(15.692307692307693,14.96606334841629),
            new Posicion(-0.7132867132867133,25.418552036199095),
            new Posicion(-14.97902097902098,35.8710407239819),
            new Posicion(14.74125874125874,35.63348416289593)
        };
    
    //GANANDO B
    Posicion alineacion2[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(7.37062937062937,-35.8710407239819),
            new Posicion(-8.083916083916083,-35.63348416289593),
            new Posicion(-10.937062937062937,-8.789592760180994),
            new Posicion(-0.951048951048951,-30.88235294117647),
            new Posicion(9.748251748251748,-8.789592760180994),
            new Posicion(-17.11888111888112,7.839366515837104),
            new Posicion(17.594405594405593,8.789592760180994),
            new Posicion(0.0,11.877828054298643),
            new Posicion(-19.97202797202797,28.031674208144796),
            new Posicion(20.447552447552447,28.50678733031674)
        };
    
	//GANANDO C
    Posicion alineacion3[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(7.37062937062937,-35.8710407239819),
            new Posicion(-8.083916083916083,-35.63348416289593),
            new Posicion(-9.510489510489512,-10.690045248868778),
            new Posicion(-0.951048951048951,-30.88235294117647),
            new Posicion(4.041958041958042,-17.57918552036199),
            new Posicion(-19.496503496503497,3.088235294117647),
            new Posicion(18.06993006993007,3.088235294117647),
            new Posicion(0.0,0.47511312217194573),
            new Posicion(-23.3006993006993,24.705882352941178),
            new Posicion(21.16083916083916,24.943438914027148)
        };
    
	//GANANDO D
    Posicion alineacion4[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(7.37062937062937,-42.047511312217196),
            new Posicion(-7.846153846153847,-41.80995475113122),
            new Posicion(-13.076923076923078,-31.59502262443439),
            new Posicion(11.888111888111888,-31.357466063348415),
            new Posicion(-0.951048951048951,-24.705882352941178),
            new Posicion(-20.685314685314687,-6.176470588235294),
            new Posicion(18.06993006993007,-6.889140271493213),
            new Posicion(0.0,0.47511312217194573),
            new Posicion(-20.447552447552447,18.766968325791854),
            new Posicion(19.496503496503497,19.2420814479638)
        };
   
    //Ataque Saca
    Posicion alineacion5[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };
    
    //Defensa Recibe
    Posicion alineacion6[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-6.419580419580419,-35.39592760180996),
            new Posicion(6.6573426573426575,-35.63348416289593),
            new Posicion(19.97202797202797,-30.6447963800905),
            new Posicion(-18.06993006993007,-30.407239819004527),
            new Posicion(29.48251748251748,-22.092760180995477),
            new Posicion(-29.72027972027972,-21.61764705882353),
            new Posicion(-12.839160839160838,-6.651583710407239),
            new Posicion(11.65034965034965,-6.176470588235294),
            new Posicion(-5.706293706293707,-11.877828054298643),
            new Posicion(3.3286713286713288,-11.877828054298643)
        };

    class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "CeutaCupWarriors";
        }

        public String getPais() {
            return "España";
        }

        public String getEntrenador() {
            return "Musta";
        }

        public Color getColorCamiseta() {
            return new Color(255, 255, 255);
        }

        public Color getColorPantalon() {
            return new Color(0, 0, 0);
        }

        public Color getColorFranja() {
            return new Color(0, 0, 0);
        }

        public Color getColorCalcetas() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero() {
            return new Color(255, 255, 255        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.FRANJA_HORIZONTAL;
        }

        public Color getColorCamiseta2() {
            return new Color(129, 251, 46);
        }

        public Color getColorPantalon2() {
            return new Color(150, 209, 135);
        }

        public Color getColorFranja2() {
            return new Color(195, 176, 171);
        }

        public Color getColorCalcetas2() {
            return new Color(123, 227, 71);
        }

        public Color getColorPortero2() {
            return new Color(177, 217, 36        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.LINEAS_HORIZONTALES;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Paquito", 1, new Color(153,102,0), new Color(255,51,51),1.0d,1.0d,1.0d, true),
                new JugadorImpl("Abdul", 2, new Color(153,102,0), new Color(204,204,0),0.9d,1.0d,0.91d, false),
                new JugadorImpl("Melki", 3, new Color(153,102,0), new Color(204,204,0),0.9d,1.0d,0.9d, false),
                new JugadorImpl("Sufian", 4, new Color(153,102,0), new Color(204,204,0),0.89d,1.0d,0.88d, false),
                new JugadorImpl("Caballa", 5, new Color(153,102,0), new Color(204,204,0),0.96d,0.4d,0.5d, false),
                new JugadorImpl("Boquer�n", 6, new Color(153,102,0), new Color(204,204,0),1.0d,0.4d,0.5d, false),
                new JugadorImpl("Barracuda", 7, new Color(153,102,0), new Color(204,204,0),0.78d,0.38d,0.5d, false),
                new JugadorImpl("At�n", 8, new Color(153,102,0), new Color(204,204,0),0.81d,0.39d,0.5d, false),
                new JugadorImpl("Musta Jr", 9, new Color(153,102,0), new Color(204,204,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Africano", 10, new Color(153,102,0), new Color(204,204,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Homer Jr", 11, new Color(153,102,0), new Color(204,204,0),1.0d,1.0d,1.0d, false)
            };
        }
    }

    TacticaDetalle detalle = new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    saco = true;
    return alineacion5;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion6;
    }
    
    private Posicion obtenerCoordenadasPortero(SituacionPartido sp)
    {
    	Posicion posPortero = new Posicion();
	    	//double radioPorteria = Constantes.LARGO_ARCO / 2;
	    	double coordAX = Constantes.centroArcoInf.getX(); //0.0
	    	double coordAY = Constantes.centroArcoInf.getY(); //-52.5
	    	double coordBX = sp.balon().getX();
	    	double coordBY = sp.balon().getY();
	    	double posPorteroY = coordAY + 3;
	    	
	    	double auxA = (posPorteroY - coordAY)*(coordBX - coordAX);
	    	double auxB = (auxA /(coordBY - coordAY));
	    	double posPorteroX = auxB + coordAX;  
	    	posPortero = sp.balon().setPosicion(posPorteroX, coordAY + 0.5);
    	return posPortero;
    }
    
    private void pasarElBalon(SituacionPartido sp, int indicePasa, int indiceRecibe)
    {
    	double distancia = sp.misJugadores()[indicePasa].distancia(sp.misJugadores()[indiceRecibe]);
    	if(distancia > MAXIMA_DISTANCIA_PASE) distancia = MAXIMA_DISTANCIA_PASE;
    	
    	//Calculo la fuerza del pase seg�n la distancia
    	double fuerza;
    	if(distancia < 16)
    		fuerza = ((distancia * 0.5) / 35) + 0.4;
    	else if(distancia < 30)
    		fuerza = ((distancia * 0.4) / 40) + 0.55;
    	else if(distancia < 39)
    		fuerza = ((distancia * 0.4) / 40) + 0.55;
    	else
    		fuerza = 1;
    	
    	//System.out.println("PASE:(" + (indiceRecibe+1) + ") F:" + fuerza + "         D: " + distancia + "m.");
    	
    	//Calculo el �ngulo de tiro seg�n la distancia
    	double angulo;
    	if (distancia <= 15 )
    		angulo = 0;
    	else if(distancia < 30)
    		angulo =  distancia * 0.8;
    	else
    		angulo = distancia * 0.7;

        comandos.add(new ComandoGolpearBalon(indicePasa, sp.misJugadores()[indiceRecibe], fuerza, angulo));
    }
    
    private void dispararPorteria(SituacionPartido sp, int indice, double distancia)
    {
    	if(distancia > 30) distancia = 30;
    	
    	//Calculo la fuerza del disparo seg�n la distancia
    	double fuerza = ((distancia * 0.3) / 30) + 0.7;
    	
    	//Calculo el �ngulo de tiro seg�n la distancia
    	double angulo = 0;
    	if (distancia > 10)
    	{
    		angulo =  (distancia * 0.9);
    	}
    	else
    	{
    		angulo = 0;
    	}
    	
        //Si estoy en la mitad derecha del campo tiro al palo derecho
        if(sp.misJugadores()[indice].getX()>0)
        {
        	comandos.add(new ComandoGolpearBalon(indice, new Posicion(Constantes.posteDerArcoSup.getX() - 3, Constantes.posteDerArcoSup.getY()), fuerza, angulo));
        }
        else //Si estoy en la izquiera tiro al palo izquiero
        {
        	comandos.add(new ComandoGolpearBalon(indice, new Posicion(Constantes.posteIzqArcoSup.getX() + 2, Constantes.posteIzqArcoSup.getY()), fuerza, angulo));
        }
    }
    
    private boolean comprobarPaseSeguro(SituacionPartido sp, Posicion jugadorPasa ,Posicion jugadorRecibe, double radioPrecision)
    {   	
    	double PasaX = jugadorPasa.getX();
    	double PasaY = jugadorPasa.getY();
    	double RecibeX = jugadorRecibe.getX();
    	double RecibeY = jugadorRecibe.getY();
    	
    	if(PasaX==RecibeX && PasaY == RecibeY)
    		return false;
    	else
    	{
    		//Si el pase se realiza paralelo al eje y (x = n)
    		if(PasaX == RecibeX)
    		{
    			if(PasaY < RecibeY)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				for(double i = PasaY; i <= RecibeY; i = i + 0.5)
    				{
    					posAux.setPosicion(PasaX, i);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * radioPrecision) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    			else if(PasaY > RecibeY)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				for(double i = PasaY; i >= RecibeY; i = i - 0.5)
    				{
    					posAux.setPosicion(PasaX, i);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * radioPrecision) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    		}
    		//Si el pase se realiza paralelo al eje x (y = n)
    		else if(PasaY == RecibeY)
    		{
    			if(PasaX < RecibeX)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				for(double i = PasaX; i <= RecibeX; i = i + 0.5)
    				{
    					posAux.setPosicion(i, PasaY);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * radioPrecision) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    			else if(PasaX > RecibeX)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				for(double i = PasaX; i >= RecibeX; i = i - 0.5)
    				{
    					posAux.setPosicion(i, PasaY);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * RADIO_SEGURIDAD_PASE) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    		}
    		//Si el pase se realiza en una trayectoria distinta(y = mx + n)
    		else
    		{
    			if(PasaX < RecibeX)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				double proporcion = (RecibeX - PasaX)/jugadorPasa.distancia(jugadorRecibe);			
    				
    				for(double i = PasaX; i <= RecibeX; i = i + (0.5 * proporcion))
    				{
    					posAux = obtenerCoordenadasPunto(PasaX, PasaY, RecibeX, RecibeY, i);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * radioPrecision) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    			else if(PasaX > RecibeX)
    			{
    				Posicion posAux = new Posicion();
    				double distanciaPuntual;
    				double radioPuntual;
    				double proporcion = (PasaX - RecibeX)/jugadorPasa.distancia(jugadorRecibe);			
    				
    				for(double i = PasaX; i >= RecibeX; i = i - (0.5 * proporcion))
    				{
    					posAux = obtenerCoordenadasPunto(PasaX, PasaY, RecibeX, RecibeY, i);
    					distanciaPuntual = distanciaEnemigoMasCercano(sp.rivales(),posAux);
    					radioPuntual = ((jugadorPasa.distancia(posAux) / jugadorPasa.distancia(jugadorRecibe)) * radioPrecision) + 0.5;
    					if(distanciaPuntual < radioPuntual)
    						return false;
    				}
    			}
    		}
    	}	
    	return true;
    }
    
    private Posicion obtenerCoordenadasPunto(double pasaX, double pasaY, double recibeX, 
    		double recibeY, double coordenadaY)
    {
    	//Creo la recta que pasa por los puntos "pasa" y "recibe"
    	//Y obtengo las coordenadas de la recta (y = coordenadaY) que corta a dicha recta
	    double auxA = (coordenadaY - pasaY)*(recibeX - pasaX);
	    double auxB = (auxA /(recibeY - pasaX));
	    double coordenadaX = auxB + pasaX;  
	    	
	    Posicion posAux = new Posicion(coordenadaX, coordenadaY);
    	return posAux;
    }
    
    private int indiceEnemigoMasCercano(Posicion[] rivales, Posicion jugador)
    {
    	double distanciaMenor = 1000;
    	int indice = -1;
    	for (int i = 0; i < 11; i++)
    	{
    		//Si la distancia es menor almanceno la del m�s cercano y guardo su indice
    		if(jugador.distancia(rivales[i]) < distanciaMenor)
    		{
    			distanciaMenor = jugador.distancia(rivales[i]);
    			indice = i;
    		}
    	}
    	if(distanciaMenor <= RADIO_SEGURIDAD_PASE) return indice;
    	
    	return -1;
    }
    
    private void huirDelEnemigoMasCercano(SituacionPartido sp, int indiceJugador)
    {
    	int indiceEnemigo = indiceEnemigoMasCercano(sp.rivales(),sp.misJugadores()[indiceJugador]);
    	if(indiceEnemigo != -1)
    	{
    		double desplazamiento = 3 + RADIO_SEGURIDAD_PASE - sp.misJugadores()[indiceJugador].distancia(sp.rivales()[indiceEnemigo]);
    		Posicion pos = new Posicion();
    		if(sp.rivales()[indiceEnemigo].getX() > sp.misJugadores()[indiceJugador].getX())
    		{
    			pos = sp.balon().setPosicion(sp.misJugadores()[indiceJugador].getX() - desplazamiento, sp.misJugadores()[indiceJugador].getY());
    		}
    		else
    		{
    			pos = sp.balon().setPosicion(sp.misJugadores()[indiceJugador].getX() + desplazamiento, sp.misJugadores()[indiceJugador].getY());
    		}
    		comandos.add(new ComandoIrA(indiceJugador, pos));
    	}
    }
    
    private double distanciaEnemigoMasCercano(Posicion[] rivales, Posicion punto)
    {
    	double distanciaMenor = 1000;
    	for (int i = 0; i < 11; i++)
    	{
    		//Si la distancia es menor almanceno la del m�s cercano y guardo su indice
    		if(punto.distancia(rivales[i]) < distanciaMenor)
    		{
    			distanciaMenor = punto.distancia(rivales[i]);
    		}
    	}
    	if(distanciaMenor < 1000) return distanciaMenor;
    	
    	//Si hay un error se retorna -1
    	return -1;
    }
    
    LinkedList<Comando> comandos = new LinkedList<Comando>();
    Random rand = new Random();
    int indiceRecibe = -1;
    boolean saco = false;
    
    ///////////////////////////////////////////////////////////////////////////////////////
    ////////                    ITERACIONES EN EJECUCI�N:              			///////////
    ///////////////////////////////////////////////////////////////////////////////////////
    public List<Comando> ejecutar(SituacionPartido sp) {
        //vacia la lista de comandos
        comandos.clear();
        
        for (int i = 1; i < 11; i++)
        {
            //El indice del jugador que Recibe no se posiciona hasta que le llegue el bal�n
            if(i != indiceRecibe)
            {
            	if(sp.balon().getY()>=4)
            	{
            		comandos.add(new ComandoIrA(i, alineacion1[i]));
            	}
	            else if(sp.balon().getY()>=-10)
	            {
	            	comandos.add(new ComandoIrA(i, alineacion2[i]));
	            }else// if(sp.balon().getY()>=-18)
	            {
	            	comandos.add(new ComandoIrA(i, alineacion3[i]));
	            }
            }
            else if(indiceRecibe != -1 && indiceRecibe != INDICE_PORTERO 
            		&& sp.balon().distancia(sp.misJugadores()[indiceRecibe]) < 20)
            {
            		comandos.add(new ComandoIrA(indiceRecibe, sp.balon()));
            }
        }
              
        //Distancia menor del rival al bal�n
        double distanciaMenorJugadorRival = sp.balon().distancia(sp.rivales()[sp.balon().indiceMasCercano(sp.rivales())]);
        double distanciaMenorMiJugador = sp.balon().distancia(sp.misJugadores()[sp.balon().indiceMasCercano(sp.misJugadores())]);
        //Si la distancia del mi jugador m�s cercano es mayor en 2 metros que la del rival
        //Voy a cubrirle
        if(distanciaMenorMiJugador >= distanciaMenorJugadorRival + 3)
        {
	        //Voy a intersectar el bal�n, antes de que llegue el contrario
	        Posicion posicionCubrir = Posicion.media(sp.balon(), sp.rivales()[sp.balon().indiceMasCercano(sp.rivales())]);      	
	        //Selecciono el jugador que va a cubrir al seleccionado
	        int indiceCercano = posicionCubrir.indiceMasCercano(sp.misJugadores());
	        //Combruebo que no sea el portero
	        if(indiceCercano != INDICE_PORTERO)
	        {
	        	comandos.add(new ComandoIrA(indiceCercano, posicionCubrir));
	        }
        }
        else //Tengo la posesi�n
        {        	
            //los 2 jugadores mas cercanos siguen al balon
            int jug1 = sp.balon().indicesMasCercanos(sp.misJugadores())[0];
            //int jug2 = sp.balon().indicesMasCercanos(sp.misJugadores())[1];
            //Posicion posic = new Posicion();
            //Posicion posic2 = new Posicion();
            //double posx = sp.misJugadores()[jug1].getX();
            //double posy = sp.misJugadores()[jug1].getY();
            //posic = sp.balon().setPosicion(posx - 7.0, posy + 7.0);
            //posic2 = sp.balon().setPosicion(posx + 7.0, posy);
            
            if(jug1 != INDICE_PORTERO)
            	comandos.add(new ComandoIrA(jug1, sp.balon()));
            //if(jug2 != INDICE_PORTERO)
            	//comandos.add(new ComandoIrA(jug2, posic));
            //if(jug3 != INDICE_PORTERO)
            	//comandos.add(new ComandoIrA(jug3, posic2));
        }
        
        //Control del portero: Solo si el bal�n est� en mi campo.
        if(sp.balon().getY()<0)
        {
        	Posicion posBalonPortero = new Posicion(); //Posici�n donde ir� el portero
        	//Si el bal�n est� dentro de un radio de ANCHO_AREA_GRANDE de la porter�a
        	if(sp.balon().distancia(Constantes.centroArcoInf) <= Constantes.ANCHO_AREA_GRANDE)
        		posBalonPortero = sp.balon(); 
        	else //Si el bal�n est� a m�s de ANCHO_AREA_GRANDE
        	{
        		posBalonPortero = obtenerCoordenadasPortero(sp);
        	}
        	comandos.add(new ComandoIrA(INDICE_PORTERO, posBalonPortero));
        }
        
        //AVANZAR
        boolean avance = false;
        if(!saco)
        {
	        int avanzo[] = sp.puedenRematar();
	        for (int h : avanzo)
	        {	
	        	Posicion rivalCercano = sp.rivales()[sp.balon().indiceMasCercano(sp.rivales())];
	        	//Si no tengo un rival cerca (A menos de 15 metros)
	        	//Y me faltan m�s de 20m para llegar a la l�nea de banda
	        	if(sp.misJugadores()[h].distancia(rivalCercano) > 7.5
	        			&& sp.misJugadores()[h].getY() < Constantes.centroArcoSup.getY() - 13
	        			&& h != INDICE_PORTERO)
	        	{
	        		if(sp.misJugadores()[h].getX() > (Constantes.ANCHO_CAMPO_JUEGO/2) - 3
	        			|| sp.misJugadores()[h].getX() < 3 - (Constantes.ANCHO_CAMPO_JUEGO/2))
	        			comandos.add(new ComandoGolpearBalon(h , Constantes.centroArcoSup, 0.40, 0));
	        		else	
	        			comandos.add(new ComandoGolpearBalon(h , sp.balon().setPosicion(sp.misJugadores()[h].getX(), Constantes.centroArcoSup.getY()), 0.40, 0));
	        		avance = true;
	        		break;
	        	}
	        }
        }
        else
        	saco = false;
	
        if(!avance)
	    {
	        //JUGADORES QUE PUEDEN PASAR
	        int rematan[] = sp.puedenRematar();
	        //recorre los jugadores que pueden rematar
	        for (int i : rematan)
	        {
	            //obtiene los jugadores mas cercanos, al jugador que puede rematar
	            int[] cercanos = sp.misJugadores()[i].indicesMasCercanos(sp.misJugadores());
	            //encontro un pase en falso
	            boolean pase = false;
	            //boolean alto;
	
	            //recorre los jugadores desde el mas lejano al mas cercano
	            for (int j = cercanos.length - 1; !pase && j >= 1; j--) 
	            {
	            	if(sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[j]]) <= MAXIMA_DISTANCIA_PASE + 5)
	            	{
	            		//si el jugador es distinto al jugador que remata y el jugador esta mas adelantado
	            		//y no tiene rivales cerca que le puedan quitar el bal�n
	            		if (sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[j]].getY()
	                		&& comprobarPaseSeguro(sp, sp.misJugadores()[i], sp.misJugadores()[cercanos[j]], RADIO_SEGURIDAD_PASE)) {
	            			pasarElBalon(sp, i, cercanos[j]);
	            			//encontro un pase por lo menos
	            			indiceRecibe = cercanos[j];
	            			pase = true;
	            		}
	            		else if(sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[j]].getY())
	            			huirDelEnemigoMasCercano(sp, j);
	            	}
	            }
	            
	            //si no encontro ningun pase Reduzco el factor de pase seguro
	            if (!pase)
	            {
	                //da pase hacia el jugador mas cercano que no tenga rivales cerca
	                for (int l = 1; !pase && l < cercanos.length; l++) 
	                {
		            	if(sp.misJugadores()[i].distancia(sp.misJugadores()[cercanos[l]]) <= MAXIMA_DISTANCIA_PASE + 5)
		            	{
		            		//si el jugador es distinto al jugador que remata y el jugador esta mas adelantado
		            		//y no tiene rivales cerca que le puedan quitar el bal�n
		            		if (sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[l]].getY()
		                		&& comprobarPaseSeguro(sp, sp.misJugadores()[i], sp.misJugadores()[cercanos[l]], RADIO_SEGURIDAD_PASE - 2)) {
		            			pasarElBalon(sp, i, cercanos[l]);
		            			//encontro un pase por lo menos
		            			indiceRecibe = cercanos[l];
		            			pase = true;
		            		}
		            		//else if(sp.misJugadores()[i].getY() < sp.misJugadores()[cercanos[l]].getY())
		            		//	huirDelEnemigoMasCercano(sp, l);
		            	}
	                }
	            }
	        
	            //si no encontro ningun pase ofensivo...
	            if (!pase)
	            {
	                //da pase hacia el jugador mas cercano que no tenga rivales cerca
	                for (int k = 1; !pase && k < cercanos.length; k++) 
	                {
	                	//Comprueba que no tenga rivales cerca que le puedan quitar el bal�n
	                	if(comprobarPaseSeguro(sp, sp.misJugadores()[i], sp.misJugadores()[cercanos[k]], RADIO_SEGURIDAD_PASE))
	                	{
			                pasarElBalon(sp, i, cercanos[k]);
			                indiceRecibe = cercanos[k];
			                pase = true;
	                	}
	                }
	            }
	            
	            //Si no encontr� ning�n pase sin rivales, golpear� el bal�n al m�s cercano
	            if(!pase)
	            {
	            	indiceRecibe = cercanos[1];
	                pasarElBalon(sp, i, cercanos[1]);
	            }
            
	            //si el jugador que remata esta a menos de 30 metros del arco rival tira a puerta
	            if(sp.misJugadores()[i].distancia(Constantes.centroArcoSup) < 30)
	            {
	            	dispararPorteria(sp, i, sp.misJugadores()[i].distancia(Constantes.centroArcoSup));
	            }  
	        }
        }
        //retorno comandos.
        return comandos;
    }
}